﻿using System;
using System.Linq;
using System.Windows;
using SoftSource.Controls;
using SoftSource.Reactive;
using SoftSource.Timecard.ViewModelInterfaces;
using SoftSource.Timecard.Views;
using SoftSource.Timecard.Web.Data;

namespace SoftSource.Timecard.Controller
{
    public sealed partial class AdministratorController : IController
    {
        #region IControllerBase Members

        public void DisplayError(Exception exception)
        {
            ErrorWindow.CreateNew(exception);
        }

        #endregion

        #region Views
        public Func<UIElement> CreateMainView
        {
            get
            {
                return () =>
                    {
                        FrameworkElement view = new MainView();

                        view.DataContext = AdministratorController.CreateMainViewModel();

                        return view;
                    };
            }
        }

        public Func<UIElement> CreateUserView
        {
            get
            {
                return () =>
                    {
                        FrameworkElement view = new UserListView();

                        view.DataContext = AdministratorController.CreateUserViewModel();

                        return view;
                    };
            }
        }

        public Func<UIElement> CreateReportView
        {
            get
            {
                return () =>
                    {
                        FrameworkElement view = new ReportListView();

                        view.DataContext = AdministratorController.CreateReportViewModel();

                        return view;
                    };
            }
        }

        public Func<UIElement> CreateSummaryView
        {
            get
            {
                return () =>
                    {
                        FrameworkElement view = new SummaryView();

                        view.DataContext = AdministratorController.CreateSummaryViewModel();

                        return view;
                    };
            }
        }

        public Func<UIElement> CreateProjectView
        {
            get
            {
                return () =>
                    {
                        FrameworkElement view = new ProjectListView();

                        view.DataContext = AdministratorController.CreateProjectViewModel();

                        return view;
                    };
            }
        }

        public Func<UIElement> CreateCategoryView
        {
            get
            {
                return () => SharedController.CreateAutoGridEditorView(
                    AdministratorController.CreateCategoryViewModel());
            }
        }

        public Func<UIElement> CreateCustomerView
        {
            get
            {
                return () => SharedController.CreateAutoGridEditorView(
                    AdministratorController.CreateCustomerViewModel());
            }
        }

        public Func<UIElement> CreateMilestoneView
        {
            get
            {
                return () => SharedController.CreateAutoGridEditorView(
                    AdministratorController.CreateMilestoneViewModel());
            }
        }

        public Func<UIElement> CreateInvoicingView
        {
            get
            {
                return () =>
                    {
                        FrameworkElement view = new InvoicingView();

                        view.DataContext = AdministratorController.CreateInvoicingViewModel();

                        return view;
                    };
            }
        }

        public Func<UIElement> CreateManagementView
        {
            get
            {
                return () =>
                    {
                        FrameworkElement view = new ManagementView();

                        view.DataContext = AdministratorController.CreateManagementViewModel();

                        return view;
                    };
            }
        }

        public Func<UIElement> CreateUpdateReminderView
        {
            get
            {
                return () =>
                    {
                        FrameworkElement view = new UpdateReminderView();

                        view.DataContext = AdministratorController.CreateUpdateReminderViewModel();

                        return view;
                    };
            }
        }

        public Func<UIElement> CreateEntryManagementView
        {
            get
            {
                return () =>
                    {
                        FrameworkElement view = new EntryManagementView();

                        view.DataContext = AdministratorController.CreateEntryManagementViewModel();

                        return view;
                    };
            }
        }

        public Func<UIElement> CreateUtilizationSummaryView
        {
            get
            {
                return () =>
                    {
                        FrameworkElement view = new UtilizationSummaryView();

                        view.DataContext = AdministratorController.CreateUtilizationSummaryViewModel();

                        return view;
                    };
            }
        }

        public Func<UIElement> CreateEntriesPriorToProjectBillingDateView
        {
            get
            {
                return () =>
                    {
                        FrameworkElement view = new EntriesPriorToProjectBillingDateView();

                        view.DataContext = AdministratorController.CreateEntriesPriorToProjectBillingDateViewModel();

                        return view;
                    };
            }
        }

        public Func<UIElement> CreateEntriesFlaggedForAdminView
        {
            get
            {
                return () =>
                    {
                        FrameworkElement view = new EntriesFlaggedForAdminView();

                        view.DataContext = AdministratorController.CreateEntriesFlaggedForAdminViewModel();

                        return view;
                    };
            }
        }

        public Func<Action<IObservable<string>>, UIElement> CreateGetUserPasswordView
        {
            get
            {
                return registerObservable =>
                    {
                        FrameworkElement view = new GetUserPasswordView();

                        view.DataContext = AdministratorController.CreateGetUserPasswordViewModel(registerObservable);

                        return view;
                    };
            }
        }
        #endregion Views

        #region Editors
        public Func<Action, UIElement> CreateNewUserEditor
        {
            get
            {
                return (Action completed) =>
                    {
                        IUserEditorViewModelService vm = AdministratorController.CreateUserEditorViewModel(completed);
                        FrameworkElement view = new UserEditorView();

                        vm.CreateUserProjectEditor = null;
                        vm.User = App.Model.Users.AddNew();

                        view.DataContext = vm;

                        return view;
                    };
            }
        }

        public Func<int, Action, UIElement> CreateUserEditor
        {
            get
            {
                return (int userID, Action completed) =>
                    {
                        IUserEditorViewModelService vm = AdministratorController.CreateUserEditorViewModel(completed);
                        FrameworkElement view = new UserEditorView();

                        view.DataContext = vm;

                        var load = App.Model
                            .LoadDataForUser(userID)
                            .Do(user => vm.User = user);
                        vm.Load = load.Once();

                        return view;
                    };
            }
        }

        public Func<Action, UIElement> CreateNewProjectEditor
        {
            get
            {
                return (Action completed) =>
                    {
                        IProjectEditorViewModelService vm = AdministratorController.CreateProjectEditorViewModel(completed);
                        FrameworkElement view = new ProjectEditorView();

                        vm.Project = App.Model.Projects.AddNew();

                        view.DataContext = vm;

                        return view;
                    };
            }
        }

        public Func<int, Action, UIElement> CreateProjectEditor
        {
            get
            {
                return (int projectID, Action completed) =>
                    {
                        IProjectEditorViewModelService vm = AdministratorController.CreateProjectEditorViewModel(completed);
                        FrameworkElement view = new ProjectEditorView();

                        view.DataContext = vm;

                        var load = App.Model
                            .LoadDataForProject(projectID)
                            .Do(project => vm.Project = project);
                        vm.Load = load.Once();

                        return view;
                    };
            }
        }

        public Func<int, Action, UIElement> CreateCloneProjectEditor
        {
            get
            {
                return (int projectID, Action completed) =>
                    {
                        IProjectEditorViewModelService vm = AdministratorController.CreateProjectEditorViewModel(completed);
                        FrameworkElement view = new ProjectEditorView();

                        view.DataContext = vm;

                        var load = App.Model
                            .LoadDataForProject(projectID)
                            .Do(project =>
                            {
                                Project newProject = new Project();
                                newProject.ActivelyUsed = project.ActivelyUsed;
                                newProject.BilledAsOf = project.BilledAsOf;
                                newProject.BillingFrequencyID = project.BillingFrequencyID;
                                newProject.EstCompletionDate = project.EstCompletionDate;
                                newProject.EstDuration = project.EstDuration;
                                newProject.ManagerUserID = project.ManagerUserID;
                                newProject.ProjectTypeID = project.ProjectTypeID;
                                newProject.RevenueTypeID = project.RevenueTypeID;
                                newProject.StatusID = project.StatusID;

                                if (project.ProjectMembers != null && project.ProjectMembers.Count > 0)
                                {
                                    foreach (ProjectMember pm in project.ProjectMembers)
                                    {
                                        ProjectMember newPM = new ProjectMember();
                                        newPM.ID = Guid.NewGuid();
                                        newPM.EndDate = pm.EndDate;
                                        newPM.HourlyRate = pm.HourlyRate;
                                        newPM.StartDate = pm.StartDate;
                                        newPM.UserID = pm.UserID;

                                        newProject.ProjectMembers.Add(newPM);
                                    }
                                }

                                if (project.ProjectCategories != null && project.ProjectCategories.Count > 0)
                                {
                                    foreach (ProjectCategory pc in project.ProjectCategories)
                                    {
                                        ProjectCategory newPC = new ProjectCategory();
                                        newPC.CategoryID = pc.CategoryID;
                                        newPC.Duration = pc.Duration;

                                        newProject.ProjectCategories.Add(newPC);
                                    }
                                }

                                App.Model.Projects.Add(newProject);
                                vm.Project = newProject;
                            });

                        vm.Load = load.Once();

                        return view;
                    };
            }
        }

        public Func<User, Action, UIElement> CreateUserProjectEditor
        {
            get
            {
                return (User user, Action completed) =>
                    {
                        FrameworkElement view = new UserProjectEditorView();

                        view.DataContext = AdministratorController.CreateUserProjectEditorViewModel(user, completed);

                        return view;
                    };
            }
        }

        public Func<Project, Action, UIElement> CreateProjectCategoryEditorView
        {
            get
            {
                return (Project project, Action completed) =>
                    {
                        FrameworkElement view = new ProjectCategoryEditorView();

                        view.DataContext = AdministratorController.CreateProjectCategoryEditorViewModel(project, completed);

                        return view;
                    };
            }
        }

        public Func<Project, Action, UIElement> CreateProjectMembershipEditorView
        {
            get
            {
                return (Project project, Action completed) =>
                    {
                        FrameworkElement view = new ProjectMembershipEditorView();

                        view.DataContext = AdministratorController.CreateProjectMembershipEditorViewModel(project, completed);

                        return view;
                    };
            }
        }

        public Func<ProjectMember, Action, UIElement> CreateProjectMemberEditorView
        {
            get
            {
                return (ProjectMember projectMember, Action completed) =>
                    {
                        FrameworkElement view = new ProjectMemberEditorView();

                        view.DataContext = AdministratorController.CreateProjectMemberEditorViewModel(projectMember, completed);

                        return view;
                    };
            }
        }

        public Func<EntryLog, Action, UIElement> CreateEntryProjectCategoryAssociationEditorView
        {
            get
            {
                return (EntryLog entry, Action completed) =>
                    {
                        FrameworkElement view = new EntryProjectCategoryAssociationEditor();

                        view.DataContext = AdministratorController.CreateEntryProjectCategoryAssociationEditorViewModel(entry, completed);

                        return view;
                    };
            }
        }
        #endregion Editors
    }
}
